home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 12 / Example 12.1 / app.cpp next >
Encoding:
C/C++ Source or Header  |  2006-08-01  |  7.7 KB  |  300 lines

  1. //////////////////////////////////////////////////////////////
  2. // Example 12.1: Billboard Effect                            //
  3. // Written by: C. Granberg, 2006                            //
  4. //////////////////////////////////////////////////////////////
  5.  
  6. #include <windows.h>
  7. #include <d3dx9.h>
  8. #include "debug.h"
  9. #include "skinnedmesh.h"
  10. #include "shader.h"
  11. #include "effect.h"
  12.  
  13. class APPLICATION
  14. {
  15.     public:
  16.         
  17.         APPLICATION();
  18.         HRESULT Init(HINSTANCE hInstance, int width, int height, bool windowed);
  19.         HRESULT Update(float deltaTime);
  20.         HRESULT Render();
  21.         HRESULT Cleanup();
  22.         HRESULT Quit();
  23.         DWORD FtoDword(float f){return *((DWORD*)&f);}
  24.  
  25.     private:
  26.         IDirect3DDevice9* m_pDevice; 
  27.         SKINNEDMESH m_skinnedMesh;
  28.         ID3DXAnimationController* m_pAnimControl;
  29.  
  30.         HWND m_mainWindow;
  31.         ID3DXFont *m_pFont;
  32.         bool m_showMagician;
  33.  
  34.         //Shaders
  35.         SHADER m_unitVS, m_unitPS;
  36.         D3DXHANDLE m_worldHandle, m_viewProjHandle, m_sunHandle, m_teamColHandle;
  37.  
  38.         //Effects 
  39.         std::vector<EFFECT*> m_effects;
  40. };
  41.  
  42. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
  43. {
  44.     APPLICATION app;
  45.  
  46.     if(FAILED(app.Init(hInstance, 800, 600, true)))return 0;
  47.  
  48.     MSG msg;
  49.     memset(&msg, 0, sizeof(MSG));
  50.     int startTime = timeGetTime(); 
  51.  
  52.     while(msg.message != WM_QUIT)
  53.     {
  54.         if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  55.         {
  56.             ::TranslateMessage(&msg);
  57.             ::DispatchMessage(&msg);
  58.         }
  59.         else
  60.         {    
  61.             int t = timeGetTime();
  62.             float deltaTime = (t - startTime)*0.001f;
  63.  
  64.             app.Update(deltaTime);
  65.             app.Render();
  66.  
  67.             startTime = t;
  68.         }
  69.     }
  70.  
  71.     app.Cleanup();
  72.  
  73.     return msg.wParam;
  74. }
  75.  
  76. APPLICATION::APPLICATION()
  77. {
  78.     m_pDevice = NULL; 
  79.     m_mainWindow = 0;
  80.     srand(GetTickCount());
  81.     m_showMagician = true;
  82. }
  83.  
  84. HRESULT APPLICATION::Init(HINSTANCE hInstance, int width, int height, bool windowed)
  85. {
  86.     debug.Print("Application initiated");
  87.  
  88.     //Create Window Class
  89.     WNDCLASS wc;
  90.     memset(&wc, 0, sizeof(WNDCLASS));
  91.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  92.     wc.lpfnWndProc   = (WNDPROC)::DefWindowProc; 
  93.     wc.hInstance     = hInstance;
  94.     wc.lpszClassName = "D3DWND";
  95.  
  96.     //Register Class and Create new Window
  97.     RegisterClass(&wc);
  98.     m_mainWindow = CreateWindow("D3DWND", "Example 12.1: Billboard Effect", WS_EX_TOPMOST, 0, 0, width, height, 0, 0, hInstance, 0); 
  99.     SetCursor(NULL);
  100.     ShowWindow(m_mainWindow, SW_SHOW);
  101.     UpdateWindow(m_mainWindow);
  102.  
  103.     //Create IDirect3D9 Interface
  104.     IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  105.  
  106.     if(d3d9 == NULL)
  107.     {
  108.         debug.Print("Direct3DCreate9() - FAILED");
  109.         return E_FAIL;
  110.     }
  111.  
  112.     //Check that the Device supports what we need from it
  113.     D3DCAPS9 caps;
  114.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
  115.  
  116.     //Hardware Vertex Processing or not?
  117.     int vp = 0;
  118.     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  119.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  120.     else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  121.  
  122.     //Check vertex & pixelshader versions
  123.     if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
  124.     {
  125.         debug.Print("Warning - Your graphic card does not support vertex and pixelshaders version 2.0");
  126.     }
  127.  
  128.     //Set D3DPRESENT_PARAMETERS
  129.     D3DPRESENT_PARAMETERS d3dpp;
  130.     d3dpp.BackBufferWidth            = width;
  131.     d3dpp.BackBufferHeight           = height;
  132.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
  133.     d3dpp.BackBufferCount            = 1;
  134.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
  135.     d3dpp.MultiSampleQuality         = 0;
  136.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
  137.     d3dpp.hDeviceWindow              = m_mainWindow;
  138.     d3dpp.Windowed                   = windowed;
  139.     d3dpp.EnableAutoDepthStencil     = true; 
  140.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
  141.     d3dpp.Flags                      = 0;
  142.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  143.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
  144.  
  145.     //Create the IDirect3DDevice9
  146.     if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_mainWindow,
  147.                                  vp, &d3dpp, &m_pDevice)))
  148.     {
  149.         debug.Print("Failed to create IDirect3DDevice9");
  150.         return E_FAIL;
  151.     }
  152.  
  153.     //Release IDirect3D9 interface
  154.     d3d9->Release();
  155.  
  156.     LoadEffectResources(m_pDevice);
  157.  
  158.     D3DXCreateFont(m_pDevice, 18, 0, 0, 1, false,  
  159.                    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
  160.                    DEFAULT_PITCH | FF_DONTCARE, "Arial", &m_pFont);
  161.  
  162.     m_skinnedMesh.Load("units/magician.x", m_pDevice);
  163.     m_skinnedMesh.SetAnimation("Still");
  164.     m_pAnimControl = m_skinnedMesh.GetAnimationControl();
  165.  
  166.     //Set sampler state
  167.     for(int i=0;i<4;i++)
  168.     {
  169.         m_pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  170.         m_pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  171.         m_pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  172.     }
  173.  
  174.     //Setup shaders
  175.     m_unitVS.Init(m_pDevice, "shaders/lighting.vs", VERTEX_SHADER);
  176.     m_worldHandle = m_unitVS.GetConstant("matW");
  177.     m_viewProjHandle = m_unitVS.GetConstant("matVP");
  178.     m_sunHandle = m_unitVS.GetConstant("DirToSun");
  179.  
  180.     m_unitPS.Init(m_pDevice, "shaders/teamCol.ps", PIXEL_SHADER);
  181.     m_teamColHandle = m_unitPS.GetConstant("tmCol");
  182.  
  183.     return S_OK;
  184. }
  185.  
  186. HRESULT APPLICATION::Update(float deltaTime)
  187. {
  188.     //Remove dead effects
  189.     std::vector<EFFECT*>::iterator i;
  190.     for(i=m_effects.begin();i != m_effects.end();)
  191.     {
  192.         if((*i)->isDead())
  193.         {
  194.             delete (*i);
  195.             m_effects.erase(i);
  196.         }
  197.         else 
  198.         {
  199.             (*i)->Update(deltaTime);
  200.             i++;
  201.         }
  202.     }
  203.  
  204.     //Keayboard input
  205.     if(KEYDOWN(VK_SPACE))
  206.     {
  207.         if(m_effects.empty())
  208.             m_effects.push_back(new EFFECT_SPELL(m_pDevice, D3DXVECTOR3(0.0f, 0.0f, 0.0f)));
  209.     }
  210.     else if(KEYDOWN(VK_RETURN))
  211.     {
  212.         m_showMagician = !m_showMagician;
  213.         Sleep(300);
  214.     }
  215.     else if(KEYDOWN(VK_ESCAPE))
  216.     {
  217.         Quit();
  218.     }
  219.  
  220.     return S_OK;
  221. }    
  222.  
  223. HRESULT APPLICATION::Render()
  224. {
  225.     // Clear the viewport
  226.     m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
  227.  
  228.     //Set camera
  229.     D3DXMATRIX view, proj, world, r, s;
  230.     D3DXMatrixLookAtLH(&view, &D3DXVECTOR3(0.0f, 20.0f, -50.0f), &D3DXVECTOR3(0.0f, 3.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
  231.     D3DXMatrixPerspectiveFovLH(&proj, 0.2f, 1.33333f, 0.01f, 1000.0f);
  232.     D3DXMatrixRotationYawPitchRoll(&r, 0.0f, 0.0f, 0.0f);
  233.     D3DXMatrixScaling(&s, 1.0f, 1.0f, 1.0f);
  234.     world = s * r;
  235.  
  236.     m_pDevice->SetTransform(D3DTS_VIEW, &view);
  237.     m_pDevice->SetTransform(D3DTS_PROJECTION, &proj);
  238.     m_pDevice->SetTransform(D3DTS_WORLD, &world);
  239.  
  240.     // Begin the scene 
  241.     if(SUCCEEDED(m_pDevice->BeginScene()))
  242.     {
  243.         if(m_showMagician)
  244.         {
  245.             m_unitVS.SetMatrix(m_worldHandle, world);
  246.             m_unitVS.SetMatrix(m_viewProjHandle, view * proj);
  247.  
  248.             D3DXVECTOR3 sun;
  249.             D3DXVec3Normalize(&sun, &D3DXVECTOR3(0.5f, 1.0f, -0.5));
  250.             m_unitVS.SetVector3(m_sunHandle, sun);
  251.  
  252.             m_unitPS.SetVector4(m_teamColHandle, D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f));
  253.  
  254.             m_unitVS.Begin();
  255.             m_unitPS.Begin();
  256.             m_skinnedMesh.SetPose(world, m_pAnimControl, 0.0f);
  257.             m_skinnedMesh.Render(NULL);
  258.             m_unitPS.End();
  259.             m_unitVS.End();
  260.         }
  261.  
  262.         //Render Effects
  263.         for(int i=0;i<m_effects.size();i++)
  264.             if(m_effects[i] != NULL)
  265.                 m_effects[i]->Render();
  266.  
  267.         RECT r[] = {{10, 10, 0, 0}, {10, 30, 0, 0}};
  268.         m_pFont->DrawText(NULL, "Space: Cast Spell", -1, &r[0], DT_LEFT| DT_TOP | DT_NOCLIP, 0xffffffff);
  269.         m_pFont->DrawText(NULL, "Return: Show Magician On/Off", -1, &r[1], DT_LEFT| DT_TOP | DT_NOCLIP, 0xffffffff);
  270.  
  271.         // End the scene.
  272.         m_pDevice->EndScene();
  273.         m_pDevice->Present(0, 0, 0, 0);
  274.     }
  275.  
  276.     return S_OK;
  277. }
  278.  
  279. HRESULT APPLICATION::Cleanup()
  280. {
  281.     try
  282.     {
  283.         UnloadEffectResources();
  284.  
  285.         m_pFont->Release();
  286.         m_pDevice->Release();
  287.  
  288.         debug.Print("Application terminated");
  289.     }
  290.     catch(...){}
  291.  
  292.     return S_OK;
  293. }
  294.  
  295. HRESULT APPLICATION::Quit()
  296. {
  297.     ::DestroyWindow(m_mainWindow);
  298.     ::PostQuitMessage(0);
  299.     return S_OK;
  300. }